import React, {
  createContext, useContext, useMemo, useEffect, useRef,
} from 'react';
import { DataSet } from 'choerodon-ui/pro';
import { observer } from 'mobx-react-lite';
import { get } from '@choerodon/inject';
import _ from 'lodash';
import { inject } from 'mobx-react';
import useStore from './useStore';
import {
  defaultTargetImageRepoDataSet,
  customTargetImageRepoDataSet,
} from './targetImageRepoDataSets';
import {
  productTypeData,
  deployWayData,
  preCommandDefault,
  runCommandDefault,
  postCommandDefault,
  dockerCommandDefault,
  killCommandDefault,
  healthProbDefault,
  valueDefault,
  dockerComposeRunCommandDefault,
} from './constants';
import buildDataSet, { mapping, transformLoadData as buildTransformLoadData }
  from '@/routes/app-pipeline/routes/app-pipeline-edit/components/pipeline-modals/build-modals/stores/buildDataSet';
import stepDataSet, { transformLoadData }
  from '@/routes/app-pipeline/routes/app-pipeline-edit/components/pipeline-modals/build-modals/stores/stepDataSet';
import auditDataSet, { transformLoadData as auditLoadData } from './auditDataSet';
import chartDeployDataSet from './chartDeployDataSet';
import deployChartDataSet from './deployChartDataSet';
import deploymentDeployDataSet from './deploymentDeployDataSet';
import deployGroupDataSet from './deployGroupDataSet';
import hostDeployDataSet from './hostDeployDataSet';
import hotJarOptionsDataSet from '@/routes/app-pipeline/routes/pipeline-manage/components/PipelineCreate/components/AddCDTask/stores/hostJarOptionsDataSet';
import apiTestDataSet from './apiTestDataSet';

interface buildModalProps {
  modal: any,
  BuildDataSet: any
  StepDataSet: any,
  // 构建数据
  data: any,
  // 设置流水线数据回调
  handleJobAddCallback: any
  // 外层高级设置数据
  advancedData: any,
  // 层级
  level: any,
  advancedRef: any,
  AuditDataSet: any,
  ChartDeployDataSet: any,
  DeployChartDataSet: any,
  buildModalUseStore: any,
  appServiceId: any,
  appServiceName: any,
  projectId: any,
  DeploymentDeployDataSet: any,
  DeployGroupDataSet: any,
  HostDeployDataSet: any,
}

const Store = createContext({} as any);

export function useBuildModalStore() {
  return useContext(Store);
}

export const StoreProvider = inject('AppState')(observer((props: any) => {
  const {
    children,
    data,
    level,
    handleJobAddCallback,
    AppState: { currentMenuType: { projectId } },
  } = props;

  const advancedRef = useRef<any>();
  const qualityAccessControlRef = useRef<any>();

  const buildModalUseStore = useStore();

  const appServiceId = data?.appService?.appServiceId;
  const appServiceName = data?.appService?.appServiceName;

  const hostGroupDeploy = get('configuration.devops-routes-pipeline-manage:hostGroupDeploy');

  const deployPayloadTypeName = get('configuration.devops-routes-pipeline-manage:fieldMap')?.deployPayloadType?.name;

  const DefaultTargetImageRepoDataSet = useMemo(
    () => new DataSet(defaultTargetImageRepoDataSet(appServiceId)), [],
  );

  const CustomTargetImageRepoDataSet = useMemo(
    () => new DataSet(customTargetImageRepoDataSet(level)), [],
  );

  console.log('level', level);

  const BuildDataSet = useMemo(() => new DataSet(
    buildDataSet(
      appServiceId,
      data,
      level,
      handleJobAddCallback,
      advancedRef,
      projectId,
    ),
  ), [appServiceId]);

  const StepDataSet = useMemo(() => new DataSet(stepDataSet(
    level,
    data,
    handleJobAddCallback,
    advancedRef,
    appServiceId,
    DefaultTargetImageRepoDataSet,
    CustomTargetImageRepoDataSet,
  )), []);

  const AuditDataSet: any = useMemo(() => new DataSet(
    auditDataSet(projectId, appServiceId, data, level),
  ), []);

  const ChartDeployDataSet: any = useMemo(() => new DataSet(
    chartDeployDataSet(
      projectId,
      buildModalUseStore,
      appServiceId,
      level,
      data?.type,
      BuildDataSet,
    ),
  ), []);

  const DeploymentDeployDataSet = useMemo(() => new DataSet(
    deploymentDeployDataSet(projectId, buildModalUseStore, level),
  ), []);

  const DeployChartDataSet = useMemo(() => new DataSet(deployChartDataSet(
    ChartDeployDataSet,
    level,
    data?.type,
  )), []);
  const DeployGroupDataSet = useMemo(() => new DataSet(
    deployGroupDataSet(DeploymentDeployDataSet, level),
  ), []);

  const ApiTestDataSet = useMemo(() => new DataSet(apiTestDataSet({
    projectId,
    useStore: buildModalUseStore,
    level,
  })), []);
  const HotJarOptionsDataSet = useMemo(() => new DataSet(hotJarOptionsDataSet(projectId)), []);

  const HostDeployDataSet = useMemo(() => new DataSet(hostDeployDataSet({
    hostGroupDeploy,
    HotJarOptionsDataSet,
    deployPayloadTypeName,
    projectId,
    useStore: buildModalUseStore,
    level,
  })), []);

  const locationValidate = async (buildDs: any, stepDs: any) => {
    async function validateRecord(record: any) {
      const res = await record.validate(true);
      return res;
    }
    for (let i = 0; i < stepDs.records.length; i += 1) {
      // eslint-disable-next-line no-await-in-loop
      const res = await validateRecord(stepDs.records[i]);
      if (!res) {
        document.querySelectorAll('.c7ncd-buildModal-content__stepItem')?.[i]?.scrollIntoView();
        break;
      }
    }
  };

  useEffect(() => {
    if (data) {
      const buildData: any = {};
      BuildDataSet.loadData([buildTransformLoadData(data, appServiceName)]);
      StepDataSet.loadData(transformLoadData(data?.devopsCiStepVOList));
      locationValidate(BuildDataSet, StepDataSet);
      switch (data.type) {
        case 'cd_audit': {
          let newData = data;
          newData = {
            ...newData,
            auditConfig: {
              ...newData?.auditConfig,
              cdAuditUserIds: newData?.auditConfig?.auditUserIds,
            },
          };
          AuditDataSet.loadData([auditLoadData(newData)]);
          break;
        }
        case 'audit': {
          AuditDataSet.loadData([auditLoadData(data)]);
          break;
        }
        case 'chart_deploy': {
          const { ciChartDeployConfig } = data;
          ChartDeployDataSet.loadData([{
            envId: ciChartDeployConfig?.envId,
            skipCheckPermission: ciChartDeployConfig?.skipCheckPermission || false,
            deployType: ciChartDeployConfig?.deployType || 'create',
          }]);
          DeployChartDataSet.loadData([{
            appId: ciChartDeployConfig?.appId || undefined,
            appName: ciChartDeployConfig?.appName || undefined,
            appCode: ciChartDeployConfig?.appCode || undefined,
            valueId: ciChartDeployConfig?.valueId,
            value: ciChartDeployConfig?.value,
          }]);
          break;
        }
        case 'cd_chart_deploy': {
          const { chartDeployCfg } = data;
          ChartDeployDataSet.loadData([{
            envId: chartDeployCfg?.envId,
            skipCheckPermission: chartDeployCfg?.skipCheckPermission || false,
            deployType: chartDeployCfg?.deployType || 'create',
          }]);
          DeployChartDataSet.loadData([{
            appId: chartDeployCfg?.appId || undefined,
            appName: chartDeployCfg?.appName || undefined,
            appCode: chartDeployCfg?.appCode || undefined,
            valueId: chartDeployCfg?.valueId,
            value: chartDeployCfg?.value,
          }]);
          // BuildDataSet?.current?.set('appServiceName', chartDeployCfg?.appServiceId);
          BuildDataSet?.current?.set('triggerValue', chartDeployCfg?.version?.split(','));
          break;
        }
        case 'deployment_deploy': {
          const { ciDeployDeployCfg } = data;
          DeploymentDeployDataSet.loadData([{
            envId: ciDeployDeployCfg?.envId,
            deployType: ciDeployDeployCfg?.deployType || 'create',
            skipCheckPermission: ciDeployDeployCfg?.skipCheckPermission || false,
          }]);
          break;
        }
        case 'api_test': {
          const { devopsCiApiTestInfoVO } = data;
          const notifyWay = [];
          if (devopsCiApiTestInfoVO?.sendEmail) {
            notifyWay.push('sendEmail');
          }
          if (devopsCiApiTestInfoVO?.sendSiteMessage) {
            notifyWay.push('sendSiteMessage');
          }
          const result = [{
            ...devopsCiApiTestInfoVO,
            taskType: devopsCiApiTestInfoVO?.taskType || 'task',
            whetherDelay: (data?.startIn && data?.startIn >= 0) || false,
            startIn: data?.startIn,
            enableWarningSetting: devopsCiApiTestInfoVO?.enableWarningSetting || false,
            blockAfterJob: !_.isNil(devopsCiApiTestInfoVO?.blockAfterJob)
              ? devopsCiApiTestInfoVO?.blockAfterJob : true,
            notifyUserIds: devopsCiApiTestInfoVO?.notifyUserIds?.split(','),
            notifyWay: notifyWay.join(','),
          }];
          ApiTestDataSet.loadData(result);
          break;
        }
        case 'host_deploy': {
          const hostData = {
            ...data?.devopsCiHostDeployInfoVO,
            // 这里是前端只有一个字段appName 但是后端还有一个appId 对应update类型的
            appName: data?.devopsCiHostDeployInfoVO?.deployType === 'update' ? data?.devopsCiHostDeployInfoVO?.appId : data?.devopsCiHostDeployInfoVO?.appName,
            hostDeployType: data?.devopsCiHostDeployInfoVO?.hostDeployType
            || productTypeData[0].value,
            deployType: data?.devopsCiHostDeployInfoVO?.deployType || deployWayData[0].value,
            deploySource: data?.devopsCiHostDeployInfoVO?.deploySource || 'pipelineDeploy',
            preCommand: data?.devopsCiHostDeployInfoVO?.preCommand || preCommandDefault,
            runCommand: data?.devopsCiHostDeployInfoVO?.runCommand || runCommandDefault,
            postCommand: data?.devopsCiHostDeployInfoVO?.postCommand || postCommandDefault,
            dockerCommand: data?.devopsCiHostDeployInfoVO?.dockerCommand || dockerCommandDefault,
            killCommand: data?.devopsCiHostDeployInfoVO?.killCommand || killCommandDefault,
            healthProb: data?.devopsCiHostDeployInfoVO?.healthProb || healthProbDefault,
            value: data?.devopsCiHostDeployInfoVO?.value || valueDefault,
            dockerComposeRunCommand: data?.devopsCiHostDeployInfoVO?.dockerComposeRunCommand
            || dockerComposeRunCommandDefault,
          };
          HostDeployDataSet.loadData([hostData]);
          break;
        }
        default: {
          break;
        }
      }
    }
  }, []);

  const value = {
    ...props,
    BuildDataSet,
    StepDataSet,
    advancedRef,
    AuditDataSet,
    buildModalUseStore,
    ChartDeployDataSet,
    DeployChartDataSet,
    appServiceId,
    appServiceName,
    projectId,
    DeploymentDeployDataSet,
    DeployGroupDataSet,
    HostDeployDataSet,
    ApiTestDataSet,
    hostGroupDeploy,
    deployPayloadTypeName,
  };
  return (
    <Store.Provider value={value}>
      {children}
    </Store.Provider>
  );
}));
